
#include "stdafx.h"

#include "winampin.h"
#define GLOBALS
#include "globals.h"

BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	
    return TRUE;
}

//Input Module Information
In_Module stMod = 
{
	IN_VER,
	"Kannan's Movie Player""(x86)"
	,
	0,	// hMainWindow
	0,  // hDllInstance
	"avi;dat;mpg;mpeg;mov;ivf;mp4;mpv;mpa;ac3;asf;ivf;m1v;mp2v;mpe;mpv2;wm;wvx;wax;wmp;wmv;qt;vob;divx;asx;ogm;m2v;ogg;mp3;mp2;mp1;wav;au;mid;midi;ac3;rmi;aif;aifc;aiff;snd\0Kannan's"
	,
	1,	// is_seekable
	1, // uses output
	About,
	About,
	Init,
	Quit,
	GetFileInfo,
	infoDlg,
	IsOurFile,
	Play,
	Pause,
	UnPause,
	IsPaused,
	Stop,
	
	GetLength,
	GetOutputTime,
	SetOutputTime,

	SetVolume,
	SetPan,

	0,0,0,0,0,0,0,0,0, // vis stuff


	0,0, // dsp

	0,

	NULL,		// setinfo

	NULL // out_mod

};

#ifdef __cplusplus
extern "C" {
#endif

__declspec( dllexport ) In_Module * winampGetInModule2()
{
	
	return &stMod;
}


#ifdef __cplusplus
}
#endif

HRESULT RegisterDll(LPSTR szDll, BOOL bRegister)
{
	LPSTR szFunction =  bRegister ? "DllRegisterServer" : "DllUnregisterServer";
	HRESULT hr = S_OK;

	HMODULE hMod = LoadLibrary(szDll);

	if (hMod != NULL)
	{
		typedef HRESULT (_stdcall *DLLPROC)();
		DLLPROC pfnDllProc = reinterpret_cast<DLLPROC>(GetProcAddress(hMod, szFunction));
		
		if (pfnDllProc)
		{
			hr = (*pfnDllProc)();
		}
				
		FreeLibrary(hMod);
	}
	return hr;
}		
void Release(void)
{
	if(stGr.pIEvent)
	{
		stGr.pIEvent->SetNotifyWindow(NULL,NULL,NULL);
		stGr.pIEvent->Release();
		stGr.pIEvent=NULL;
	}
	if(stGr.pIVideoWindow)
	{
		stGr.pIVideoWindow->put_Owner(NULL);
		stGr.pIVideoWindow->put_MessageDrain(NULL);
		stGr.pIVideoWindow->put_Visible(OAFALSE);
		stGr.pIVideoWindow->Release();
		stGr.pIVideoWindow=NULL;
	}
	if(stGr.pIBasicAudio)
	{
		stGr.pIBasicAudio->Release();
		stGr.pIBasicAudio=NULL;
	}
	if(stGr.pIBasicVideo)
	{
		stGr.pIBasicVideo->Release();
		stGr.pIBasicVideo=NULL;
	}
	if(stGr.pIMediaControl)
	{
		stGr.pIMediaControl->Release();
		stGr.pIMediaControl=NULL;
	}
	if(stGr.pIMediaPosition)
	{
		stGr.pIMediaPosition->Release();
		stGr.pIMediaPosition=NULL;
	}
	if(stGr.pIVideoEffect)
	{
		stGr.pIVideoEffect->Release();
		stGr.pIVideoEffect=NULL;
	}
	if(stGr.pIAudioEffect)
	{
		stGr.pIAudioEffect->Release();
		stGr.pIAudioEffect=NULL;
	}


    if(stGr.pVideoEffectFilter)
	{
		stGr.pGraphFilter->RemoveFilter(stGr.pVideoEffectFilter);
		stGr.pVideoEffectFilter->Release();
		stGr.pVideoEffectFilter=NULL;
	}
	if(stGr.pAudioEffectFilter)
	{
		stGr.pGraphFilter->RemoveFilter(stGr.pAudioEffectFilter);
		stGr.pAudioEffectFilter->Release();
		stGr.pAudioEffectFilter=NULL;
	}
	if(stGr.pColorSpaceFilter)
	{
		stGr.pGraphFilter->RemoveFilter(stGr.pColorSpaceFilter);
		stGr.pColorSpaceFilter->Release();
		stGr.pColorSpaceFilter=NULL;
	}
	if(stGr.pAudioDecoderFilter)
	{
		stGr.pGraphFilter->RemoveFilter(stGr.pAudioDecoderFilter);
		stGr.pAudioDecoderFilter->Release();
		stGr.pAudioDecoderFilter = NULL;
	}
	if(stGr.pVideoDecoderFilter)
	{
		stGr.pGraphFilter->RemoveFilter(stGr.pVideoDecoderFilter);
		stGr.pVideoDecoderFilter->Release();
		stGr.pVideoDecoderFilter = NULL;
	}

	if(stGr.pVideoRenderFilter)
	{
		stGr.pGraphFilter->RemoveFilter(stGr.pVideoRenderFilter);
		stGr.pVideoRenderFilter->Release();
		stGr.pVideoRenderFilter=NULL;
	}
	if(stGr.pGraphFilter)
	{
		stGr.pGraphFilter->Release();
		stGr.pGraphFilter=NULL;
	}
	
}



void About(HWND hwndparent)
{
	DialogBox(stMod.hDllInstance,MAKEINTRESOURCE(IDD_MAINCONFIGURE),hwndparent,(DLGPROC)ConfigMainproc);
}

void Init(void)
{
	WNDCLASSEX wsxf;
	WNDCLASSEX wsx;

	ZeroMemory((void*)&wsx,sizeof(WNDCLASSEX));

	wsx.cbSize = sizeof(WNDCLASSEX);
	wsx.lpfnWndProc = MainWindowproc;
	wsx.lpszClassName = CLASSNAME;
	wsx.hInstance = stMod.hDllInstance;
	wsx.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
	wsx.hbrBackground = CreateSolidBrush(RGB(0,0,0));
		
	if(!RegisterClassEx(&wsx))
	{
		DisplayInfo("Movie Window Class Registration Error","Error");
	}

	ZeroMemory((void*)&wsxf,sizeof(WNDCLASSEX));

	wsxf.cbSize = sizeof(WNDCLASSEX);
	wsxf.lpfnWndProc = CustomFullScreenWndproc;
	wsxf.lpszClassName = FULLCLASSNAME;
	wsxf.hInstance = stMod.hDllInstance;
	wsxf.style = CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;
	wsxf.hbrBackground = CreateSolidBrush(RGB(0,0,0));

	if(!RegisterClassEx(&wsxf))
	{
		DisplayInfo("Fullscreen Window Class Registration Error","Error");
	}

	CoInitialize(NULL);
			
	stInfo.EnableEffect = GetPrivateProfileInt("Kannan","Effect",0,"Plugin.ini");
	stInfo.EnableDSPEffect = GetPrivateProfileInt("Kannan","DspEffect",1,"Plugin.ini");
	stInfo.EnableAspectRatio = GetPrivateProfileInt("Kannan","AspectRatio",1,"Plugin.ini");
	stInfo.EnableSmooth = GetPrivateProfileInt("Kannan","Smooth",0,"Plugin.ini");
	stInfo.EnableAutoSkin = GetPrivateProfileInt("Kannan","AutoSkin",1,"Plugin.ini");
	stInfo.EnableExtEff = GetPrivateProfileInt("Kannan","ExtEff",0,"Plugin.ini");
	stAmod.Enable = GetPrivateProfileInt("Kannan","EnableampOut",0,"Plugin.ini");
	stInfo.iSetRenderMethod = GetPrivateProfileInt("Kannan","SetRenderMethod",0,"Plugin.ini");
	stInfo.iDecodeMethod = GetPrivateProfileInt("Kannan","DecodeMethod",0,"Plugin.ini");
	stInfo.iAudioEffectMethod = GetPrivateProfileInt("Kannan","AudioEffectMethod",0,"Plugin.ini");
	stInfo.iVideoEffectMethod = GetPrivateProfileInt("Kannan","VideoEffectMethod",0,"Plugin.ini");
	
		
	stInfo.iSkinCount = 0;
	stInfo.FullScreenFlag = FALSE;

	InitSkinDir();
	InitSkin();
	InitFilterMenu();
		
	stInfo.CapHeight = GetSystemMetrics(SM_CYSMCAPTION)+GetSystemMetrics(SM_CYFRAME);
	stInfo.Xborder = GetSystemMetrics(SM_CXFRAME);
	stInfo.Yborder = GetSystemMetrics(SM_CYFRAME);

		
	stInfo.hmenumain = GetSubMenu(LoadMenu(stMod.hDllInstance,MAKEINTRESOURCE(IDR_FILE)),0);
	InsertMenu(stInfo.hmenumain,GetMenuItemCount(stInfo.hmenumain)-1,MF_POPUP|MF_BYPOSITION,(UINT)stInfo.hMenuSkin,"Skin");
	InsertMenu(stInfo.hmenumain,GetMenuItemCount(stInfo.hmenumain)-2,MF_POPUP|MF_BYPOSITION,(UINT)stInfo.hMenuMainEffect,"Effect");	

	CheckMenuItem(stInfo.hMenuMainEffect,GetPrivateProfileInt("Kannan","Effectno",0,"Plugin.ini")+ID_EFFECT,MF_BYCOMMAND|MF_CHECKED);
	

	{
		int iIndex;
		char str[MAX_PATH];
		int flag = 1;

		ZeroMemory(str,MAX_PATH);
		GetPrivateProfileString("Kannan","ExtEffStr",0,str,sizeof(str),"Plugin.ini");
		for(iIndex = 0;iIndex < stInfo.iExternalEffectCount;iIndex++)
		{
			if(!strcmp(stExteff[iIndex].Path,str))
			{
				flag = 0;
				CheckMenuItem(stInfo.hMenuEffect[INDEX_OF_EXEFF],stExteff[iIndex].Menuid,MF_BYCOMMAND|MF_CHECKED);
			}
		}
		if(flag)
		{
			CheckMenuItem(stInfo.hMenuEffect[INDEX_OF_EXEFF],0,MF_BYPOSITION|MF_CHECKED);
		}
	}
	
}

void Quit(void)
{
	int iIndex;
	
	for(iIndex = 0; iIndex < MAX_SUB_EFF_MENU;iIndex++)
	{
		DestroyMenu(stInfo.hMenuEffect[iIndex]);
	}
	DestroyMenu(stInfo.hMenuMainEffect);
	DestroyMenu(stInfo.hMenuSkin);
	DestroyMenu(stInfo.hmenumain);
	UnloadSkin();

	DestroyWindow(stInfo.hwnd);

	UnregisterClass(CLASSNAME,stMod.hDllInstance);
	UnregisterClass(FULLCLASSNAME,stMod.hDllInstance);
	CoUninitialize();
}

int IsOurFile(char *filename)
{
	HRESULT hr;
	IGraphBuilder *pGraphFilter;
	WCHAR wfilename[MAX_PATH];
	char strTemp[EXT_BUF_SIZE];
	size_t numConverted;
	
	ZeroMemory(strTemp,EXT_BUF_SIZE);

	strcpy_s(strTemp,strrchr(filename,'.')+1);

	_strlwr_s(strTemp,EXT_BUF_SIZE);
	
	if(!strcmp(strTemp,"mp3"))
	{
		return 0;
	}
	else if(!strcmp(strTemp,"wav"))
	{
		return 0;
	}
	else if(!strcmp(strTemp,"mp2"))
	{
		return 0;
	}
	else if(!strcmp(strTemp,"mp1"))
	{
		return 0;
	}
	else if(!strcmp(strTemp,"mid"))
	{
		return 0;
	}
		
	CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(void**)&pGraphFilter);
	mbstowcs_s(&numConverted,wfilename,filename,sizeof(wfilename));
	hr=pGraphFilter->RenderFile(wfilename,0);

	if(SUCCEEDED(hr))
	{
		pGraphFilter->Release();
		pGraphFilter=NULL;
		return -1;
	
	}

	pGraphFilter->Release();
	pGraphFilter=NULL;

	return 0;
}

int Play(char *filename)
{
	long lVisible;
	HRESULT hr;
	WCHAR wfilename[MAX_PATH];
	RECT r,r1;
	POINT moviesize;
	size_t numConverted;
		
	SetFileName(filename);

	InitPlay();
	//conver the filename to wchar format
	mbstowcs_s(&numConverted,wfilename,filename,sizeof(wfilename));
	//create the render graph based on the file
	hr=stGr.pGraphFilter->RenderFile(wfilename, NULL);

	if(SUCCEEDED(hr))
	{
		//Query the all interfaces
		stGr.pGraphFilter->QueryInterface(IID_IMediaControl, (void **)&stGr.pIMediaControl);
		stGr.pGraphFilter->QueryInterface(IID_IVideoWindow, (void **)&stGr.pIVideoWindow);
		stGr.pGraphFilter->QueryInterface(IID_IMediaPosition, (void **)&stGr.pIMediaPosition);
		stGr.pGraphFilter->QueryInterface(IID_IBasicAudio,(void**)&stGr.pIBasicAudio);
		stGr.pGraphFilter->QueryInterface(IID_IBasicVideo,(void**)&stGr.pIBasicVideo);
		stGr.pGraphFilter->QueryInterface(IID_IMediaEventEx,(void**)&stGr.pIEvent);
        //create the display window
		stInfo.hwnd=CreateWindowEx(WS_EX_TOOLWINDOW|WS_EX_ACCEPTFILES,CLASSNAME,"Kannan's",\
		WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME,0,0,0,0,stMod.hMainWindow,0,stMod.hDllInstance,0);

	    //load skin
		LoadSkin();

		//set the notify window
		if(stGr.pIEvent)
		{
			stGr.pIEvent->SetNotifyWindow((OAHWND)stInfo.hwnd,WM_GRAPHNOTIFY,0);
		}
        //set the video window   			
		if(stGr.pIVideoWindow)
		{
			stGr.pIVideoWindow->put_Owner((OAHWND)stInfo.hwnd);
			stGr.pIVideoWindow->put_WindowStyle(WS_CHILD|WS_CLIPSIBLINGS|WS_VISIBLE);
			stGr.pIVideoWindow->put_MessageDrain((OAHWND)stInfo.hwnd);
			stGr.pIVideoWindow->put_Visible(OATRUE);
			stGr.pIVideoWindow->put_WindowState(SW_SHOW);
			stGr.pIVideoWindow->HideCursor(OATRUE);
            //set the default window size based on the aspect ratio
			moviesize.x=352;
			moviesize.y=288;
			if(stGr.pIBasicVideo)
			{
				stGr.pIBasicVideo->GetVideoSize(&moviesize.x,&moviesize.y);
			}
		
			if(moviesize.x > 352)
			{
				moviesize.x = 352;
			}
			if(moviesize.y > 288)
			{
				moviesize.y = 288;
			}
        
			GetWindowRect(stMod.hMainWindow,&r);
			r1=r;
	
			if((r.right+moviesize.x)>GetSystemMetrics(SM_CXSCREEN))
			{
				r.right = r.left - moviesize.x;
			}
			if(r.right<0)
			{
				r.right = (GetSystemMetrics(SM_CXSCREEN) / 2)-(moviesize.x / 2);
				r.top = r.top + (r.bottom - r.top);
			}
	
			if((r.top + moviesize.y) > GetSystemMetrics(SM_CYSCREEN))
			{
				r.top = GetSystemMetrics(SM_CYSCREEN) - moviesize.y;
					if((r.top + moviesize.y) > r1.top)
					{
						r.top = r1.top-moviesize.y;
					}
			}
			if(r.top < 0)
			{
				r.top=0;
			}
			//set the window pos
			SetWindowPos(stInfo.hwnd,0,r.right,r.top,moviesize.x,moviesize.y,FALSE);
			GetClientRect(stInfo.hwnd,&r);
			stGr.pIVideoWindow->SetWindowPosition(0,0,r.right,r.bottom);
		}
		//start playing	
		if(stGr.pIMediaControl)
		{
			SendMessage(stMod.hMainWindow,WM_COMMAND,40058,0);
			SendMessage(stMod.hMainWindow,WM_COMMAND,40059,0);
			if(SUCCEEDED(stGr.pIVideoWindow->get_Visible(&lVisible)))
			{
				ShowWindow(stInfo.hwnd,SW_SHOW);
			}
			stGr.pIMediaControl->Run();
			return 0;
		}
	}
	return -1;
}

void Pause(void)
{
	if(stGr.pIMediaControl)
	{
		stGr.pIMediaControl->Pause();
	}
}

void UnPause(void)
{
	if(stGr.pIMediaControl)
	{
		stGr.pIMediaControl->Run();
	}
}

int IsPaused(void)
{
	OAFilterState ofs;

	if(stGr.pIMediaControl)
	{
		stGr.pIMediaControl->GetState(INFINITE,&ofs);
		if(ofs == State_Paused)
		{
			return 1;
		}
	}
	return 0;
}

void Stop(void)
{

	if(stGr.pIVideoEffect)
	{
		stGr.pIVideoEffect->SetStop();
	}
	if(stGr.pIAudioEffect)
	{
		stGr.pIAudioEffect->SetStop();
	}
	if(stGr.pIMediaControl)
	{
		stGr.pIMediaControl->Stop();
	}

	Release();

	DestroyWindow(stInfo.hwnd);
	DestroyWindow(stInfo.hwndfull);

}

int GetLength(void)
{

	REFTIME reftime;
	if(stGr.pIMediaPosition)
	{
		stGr.pIMediaPosition->get_Duration(&reftime);
		return (int)(reftime*1000);
	
	}
	return 0;
}

//Initilize the skin
void InitSkinDir(void)
{
	char str[MAX_PATH],strpath[MAX_PATH];
	WIN32_FIND_DATA fd;
	HANDLE fh;
	int iIndex;

    //Fill buf with 0
	ZeroMemory(str,MAX_PATH);
	ZeroMemory(strpath,MAX_PATH);
    
	//get the CWD
	GetModuleFileName(stMod.hDllInstance,str,MAX_PATH);
	strncpy_s(strpath,str,(strrchr(str,'\\')-str)+1);
	strcpy_s(stInfo.Path,strpath);
	//make the skin path
	strcat_s(strpath,"KannanSkin\\");
	strcat_s(strpath,"*.bmp");
    //create the skin popup menu
	stInfo.hMenuSkin=CreateMenu();

	iIndex=0;
    //set the default menu
	strcpy_s(stskm[iIndex].Path,"Jill.kzh");
	stskm[iIndex].Menuid=ID_PLUGIN+iIndex;
	AppendMenu(stInfo.hMenuSkin,MF_STRING,stskm[iIndex].Menuid,"Default Skin");

	iIndex++;
    //start skin finding...
	fh=FindFirstFile(strpath,&fd);

	if(fh!=INVALID_HANDLE_VALUE)
	{
		//copy the filename with path
		strcpy_s(stskm[iIndex].Path,fd.cFileName);
        //fill with zero
		ZeroMemory(str,MAX_PATH);
		//get the filename without file ext
		strncpy_s(str,stskm[iIndex].Path,(strrchr(stskm[iIndex].Path,'.')-stskm[iIndex].Path));
        //make the menu id
		stskm[iIndex].Menuid=ID_PLUGIN+iIndex;
		//append the menu
		AppendMenu(stInfo.hMenuSkin,MF_STRING,stskm[iIndex].Menuid,str);
		//do Iteration
		iIndex++;
		while(FindNextFile(fh,&fd) && iIndex < NO_OF_SKINMENU)
		{	//do the above process
			strcpy_s(stskm[iIndex].Path,fd.cFileName);
			ZeroMemory(str,MAX_PATH);
		
			strncpy_s(str,stskm[iIndex].Path,(strrchr(stskm[iIndex].Path,'.')-stskm[iIndex].Path));
			stskm[iIndex].Menuid=ID_PLUGIN+iIndex;
			AppendMenu(stInfo.hMenuSkin,MF_STRING,stskm[iIndex].Menuid,str);

			iIndex++;
		}
		stInfo.iSkinCount=iIndex;
	}
}

int GetOutputTime(void)
{
	REFTIME reftime;
	int iMilliSecond=0;
	//get the current media time
	if(stGr.pIMediaPosition)
	{
		stGr.pIMediaPosition->get_CurrentPosition(&reftime);
		iMilliSecond=(int)(reftime*1000);
				
	}
	return iMilliSecond;
}

void SetOutputTime(int iMilliSecond)
{
	//set the current output time
	if(stGr.pIMediaPosition)
	{
		stGr.pIMediaPosition->put_CurrentPosition((REFTIME)iMilliSecond/1000);
	}
}

void SetVolume(int iPoint)
{
	if(stAmod.Enable)
	{
		stMod.outMod->SetVolume(iPoint);
	}
	else
	{
		if(stGr.pIBasicAudio)
		{
			if(iPoint==0)
			{
				stGr.pIBasicAudio->put_Volume(-10000);
			}
			else
			{
				stGr.pIBasicAudio->put_Volume((long)(((iPoint - 255) / 255.0) * 3000));
			}
		}
	}
}

void SetPan(int iPan)
{
	if(stAmod.Enable)
	{
		stMod.outMod->SetPan(iPan);
	}
	else
	{
		if(stGr.pIBasicAudio)
		{
			if(iPan==-127)
			{
				stGr.pIBasicAudio->put_Balance(-10000);
			}
			else if(iPan==127)
			{
				stGr.pIBasicAudio->put_Balance(10000);
			}
			else
			{
				stGr.pIBasicAudio->put_Balance((long)((iPan / 127.0) * 2000));
			}
		}
	}
	
}

void GetFileInfo(char *file, char *title, int *length_in_ms)
{
	if(!file || !*file)
	{
		file=stInfo.PlayingFileName;
	}
	else
	{
		SetFileName(file);
		file=stInfo.PlayingFileName;
	}
	if(title)
	{
		sprintf_s(title,MAX_PATH,"%s Kannan's",file);
	}
	if(length_in_ms)
	{
		*length_in_ms = GetLength();
	}
}

//movie info
int infoDlg(char *FileName, HWND hwnd)
{
	long lx,ly;
	lx=ly=0;
	char str [BUFSIZ],strTemp[SMALL_BUF_SIZE];
	sprintf_s(str,"Filename            : %s\n",FileName);

	if(stGr.pIBasicVideo)
	{
		stGr.pIBasicVideo->GetVideoSize(&lx,&ly);
		sprintf_s(strTemp,"PictureSize         : %ld x %ld\n",lx,ly);
		strcat_s(str,strTemp);
	}
	DisplayInfo(str,"Kannan's Movie stInfo");
	return 0;
}

//set filename
void SetFileName(char* filename)
{
	strcpy_s(stInfo.PlayingFileName,(strrchr(filename,'\\')+1));
}

//initilize the all filter interfaces
void InitPlay(void)
{
	CoInitialize(NULL);
	//default fullscreen is false
	stInfo.FullScreenFlag = FALSE;
	//default Filter Propery Page is not shown
	stInfo.ShowFilterProperty = FALSE;
    //create the filter graph
    CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC,IID_IGraphBuilder,(void**)&stGr.pGraphFilter);

    SelectRenderFilter();

	//add to the pool
	if(stGr.pVideoRenderFilter)
	{
		stGr.pGraphFilter->AddFilter(stGr.pVideoRenderFilter,L"VideoRenderer");
	}

	SelectDecodeFilter();

	if(stGr.pAudioDecoderFilter)
	{
		stGr.pGraphFilter->AddFilter(stGr.pAudioDecoderFilter,L"AudioDecoder");
	}
	if(stGr.pVideoDecoderFilter)
	{
		stGr.pGraphFilter->AddFilter(stGr.pVideoDecoderFilter,L"VideoDecoder");
	}

	//check for the dsp effect
	if(stInfo.EnableDSPEffect)
	{
		SelectAudioEffectFilter();

		if(stGr.pAudioEffectFilter)
		{
			stGr.pGraphFilter->AddFilter(stGr.pAudioEffectFilter,L"AudioEffect");
		}
		
	}
    //check for the image effect enabled
	if(stInfo.EnableEffect)
	{
		SelectVideoEffectFilter();

		//add to the pool
		if(stGr.pVideoEffectFilter)
		{
			stGr.pGraphFilter->AddFilter(stGr.pVideoEffectFilter,L"Video Effect");
		}
	}
	SendMessage(stInfo.hwndfull,WM_CLOSE,0,0);
}

BOOL CALLBACK Configproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	char strTemp[STR_BUF];

	switch(msg)
	{
	case WM_INITDIALOG:
		{	
			RECT r;
			POINT stPoint;
			int iIndex;

			GetWindowRect(GetDlgItem(GetParent(hwnd),IDC_STATIC1),&r);
			stPoint.x = r.left;
			stPoint.y = r.top;
			ScreenToClient(GetParent(hwnd),&stPoint);
			SetWindowPos(hwnd,0,stPoint.x,stPoint.y,r.right-r.left,r.bottom-r.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);

			for(iIndex = 0 ; iIndex < TOT_NO_OF_RENDER_TYPES ; iIndex++)
			{
                SendDlgItemMessage(hwnd,IDC_RENDERMETHOD,CB_ADDSTRING,0,(LPARAM)RenderTypes[iIndex]);
			}

			SendDlgItemMessage(hwnd,IDC_RENDERMETHOD,CB_SETCURSEL,stInfo.iSetRenderMethod,0);

			for(iIndex = 0 ; iIndex < TOT_NO_OF_DECODE_TYPES ; iIndex++)
			{
                SendDlgItemMessage(hwnd,IDC_PACKAGE,CB_ADDSTRING,0,(LPARAM)DecodeTypes[iIndex]);
			}

			SendDlgItemMessage(hwnd,IDC_PACKAGE,CB_SETCURSEL,stInfo.iDecodeMethod,0);

			for(iIndex = 0 ; iIndex < TOT_NO_OF_AUDIOEFFECT_TYPES ; iIndex++)
			{
                SendDlgItemMessage(hwnd,IDC_AUDIOEFFPACK,CB_ADDSTRING,0,(LPARAM)AudioEffectTypes[iIndex]);
			}

			SendDlgItemMessage(hwnd,IDC_AUDIOEFFPACK,CB_SETCURSEL,stInfo.iAudioEffectMethod,0);

			for(iIndex = 0 ; iIndex < TOT_NO_OF_VIDEOEFFECT_TYPES ; iIndex++)
			{
                SendDlgItemMessage(hwnd,IDC_VIDEOEFFPACK,CB_ADDSTRING,0,(LPARAM)VideoEffectTypes[iIndex]);
			}

			SendDlgItemMessage(hwnd,IDC_VIDEOEFFPACK,CB_SETCURSEL,stInfo.iVideoEffectMethod,0);
	
			if(stAmod.Enable)
			{
				SendDlgItemMessage(hwnd,IDC_USEOUTPUT,BM_SETCHECK,BST_CHECKED,0);
			}
			if(stInfo.EnableExtEff)
			{
				SendDlgItemMessage(hwnd,IDC_EXTEFF,BM_SETCHECK,BST_CHECKED,0);
			}
			if(stInfo.EnableEffect)
			{
				SendDlgItemMessage(hwnd,IDC_IMAGEEFF,BM_SETCHECK,BST_CHECKED,0);
			}
			if(stInfo.EnableDSPEffect)
			{
				SendDlgItemMessage(hwnd,IDC_EQUALIZER,BM_SETCHECK,BST_CHECKED,0);
			}
			if(stInfo.EnableAspectRatio)
			{
				SendDlgItemMessage(hwnd,IDC_ASPECTRATIO,BM_SETCHECK,BST_CHECKED,0);
			}
			if(stInfo.EnableSmooth)
			{
				SendDlgItemMessage(hwnd,IDC_SMOOTHING,BM_SETCHECK,BST_CHECKED,0);
			}
			if(stInfo.EnableAutoSkin)
			{
				SendDlgItemMessage(hwnd,IDC_AUTOSKIN,BM_SETCHECK,BST_CHECKED,0);
			}
		}
		break;
	case WM_COMMAND:
		switch(LOWORD(wparam))
		{
			case IDC_VIDEOEFFPACK:
				stInfo.iVideoEffectMethod = SendDlgItemMessage(hwnd,IDC_VIDEOEFFPACK,CB_GETCURSEL,0,0);
				sprintf_s(strTemp,"%d",stInfo.iVideoEffectMethod);
                WritePrivateProfileString("Kannan","VideoEffectMethod",strTemp,"Plugin.ini");
				break;
			case IDC_AUDIOEFFPACK:
				stInfo.iAudioEffectMethod = SendDlgItemMessage(hwnd,IDC_AUDIOEFFPACK,CB_GETCURSEL,0,0);
				sprintf_s(strTemp,"%d",stInfo.iAudioEffectMethod);
                WritePrivateProfileString("Kannan","AudioEffectMethod",strTemp,"Plugin.ini");
				break;
			case IDC_PACKAGE:
				stInfo.iDecodeMethod = SendDlgItemMessage(hwnd,IDC_PACKAGE,CB_GETCURSEL,0,0);
				sprintf_s(strTemp,"%d",stInfo.iDecodeMethod);
                WritePrivateProfileString("Kannan","DecodeMethod",strTemp,"Plugin.ini");
			break;
			case IDC_RENDERMETHOD:
				stInfo.iSetRenderMethod = SendDlgItemMessage(hwnd,IDC_RENDERMETHOD,CB_GETCURSEL,0,0);
				sprintf_s(strTemp,"%d",stInfo.iSetRenderMethod);
                WritePrivateProfileString("Kannan","SetRenderMethod",strTemp,"Plugin.ini");
				break;
            case IDC_EXTEFF:
                stInfo.EnableExtEff = !stInfo.EnableExtEff;
				sprintf_s(strTemp,"%d",stInfo.EnableExtEff);
				WritePrivateProfileString("Kannan","ExtEff",strTemp,"Plugin.ini");
				if(stGr.pIVideoEffect)
				{
					stGr.pIVideoEffect->SetExtEff(stInfo.EnableExtEff);
				}
				break;
			case IDC_USEOUTPUT:
				stAmod.Enable = !stAmod.Enable;
				sprintf_s(strTemp,"%d",stAmod.Enable);
				WritePrivateProfileString("Kannan","EnableampOut",strTemp,"Plugin.ini");
				break;
			case IDC_EQUALIZER:
				stInfo.EnableDSPEffect = !stInfo.EnableDSPEffect;
				sprintf_s(strTemp,"%d",stInfo.EnableDSPEffect);
				WritePrivateProfileString("Kannan","DspEffect",strTemp,"Plugin.ini");
				if(!stGr.pAudioEffectFilter)
				{
					SendMessage(stMod.hMainWindow,WM_COMMAND,WINAMP_BUTTON4,0);
					SendMessage(stMod.hMainWindow,WM_COMMAND,WINAMP_BUTTON2,0);
				}
				break;
			case IDC_AUTOSKIN:
				stInfo.EnableAutoSkin = !stInfo.EnableAutoSkin;
				sprintf_s(strTemp,"%d",stInfo.EnableAutoSkin);
				WritePrivateProfileString("Kannan","AutoSkin",strTemp,"Plugin.ini");
				break;
			case IDC_IMAGEEFF:
				stInfo.EnableEffect = !stInfo.EnableEffect;
				sprintf_s(strTemp,"%d",stInfo.EnableEffect);
				WritePrivateProfileString("Kannan","Effect",strTemp,"Plugin.ini");
				if(stGr.pGraphFilter)
				{
					SendMessage(stMod.hMainWindow,WM_COMMAND,WINAMP_BUTTON4,0);
					SendMessage(stMod.hMainWindow,WM_COMMAND,WINAMP_BUTTON2,0);
				}
				break;
			case IDC_ASPECTRATIO:
				stInfo.EnableAspectRatio = !stInfo.EnableAspectRatio;
				sprintf_s(strTemp,"%d",stInfo.EnableAspectRatio);
				WritePrivateProfileString("Kannan","EnableAspectRatio",strTemp,"Plugin.ini");
				break;
			case IDC_SMOOTHING:
				stInfo.EnableSmooth = !stInfo.EnableSmooth;
				sprintf_s(strTemp,"%d",stInfo.EnableSmooth);
				WritePrivateProfileString("Kannan","Smooth",strTemp,"Plugin.ini");
				if(stGr.pIVideoEffect)
				{
					stGr.pIVideoEffect->SetSmooth(stInfo.EnableSmooth);
				}
				break;
		}
		break;
	case WM_CLOSE:
		EndDialog(hwnd,0);
		return TRUE;
	}
	return FALSE;
}
BOOL CALLBACK ConfigMainproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{

	switch(msg)
	{
	case WM_DRAWITEM:
		{
			LPDRAWITEMSTRUCT lpdraw;
			RECT r;
			char str[SMALL_BUF_SIZE];

			lpdraw=(LPDRAWITEMSTRUCT)lparam;

			//if(lpdraw->CtlID == stInfo.AboutID)
			if(lpdraw->itemState&(ODS_FOCUS|ODS_DEFAULT))
			{
				SetTextColor(lpdraw->hDC,RGB(0,0,255));
			}

			GetClientRect(lpdraw->hwndItem,&r);
			GetWindowText(lpdraw->hwndItem,str,30);
			DrawText(lpdraw->hDC,str,-1,&r,DT_VCENTER|DT_CENTER|DT_SINGLELINE);
			if(lpdraw->CtlID!=IDC_ABOUT)
			{
				POINT pt[2];
				pt[0].x=0;
				pt[0].y=0;
				pt[1].x=0;
				pt[1].y=r.bottom;
				Polyline(lpdraw->hDC,pt,2);
			}
		}
		return 1;
	case WM_COMMAND:
        switch(LOWORD(wparam))
		{
		case IDC_ABOUT:
			DestroyWindow(stInfo.hWndAbout);
			stInfo.hWndAbout=CreateDialog(stMod.hDllInstance,MAKEINTRESOURCE(IDD_ABOUT),hwnd,(DLGPROC)Aboutproc);
			ShowWindow(stInfo.hWndAbout,SW_SHOW);
			SetFocus(GetDlgItem(hwnd,IDC_ABOUT));
			stInfo.AboutID = IDC_ABOUT;
			break;
		case IDC_CONFIGURE:
			DestroyWindow(stInfo.hWndAbout);
			stInfo.hWndAbout=CreateDialog(stMod.hDllInstance,MAKEINTRESOURCE(IDD_CONFIGURE),hwnd,(DLGPROC)Configproc);
			ShowWindow(stInfo.hWndAbout,SW_SHOW);
			SetFocus(GetDlgItem(hwnd,IDC_CONFIGURE));
			stInfo.AboutID = IDC_CONFIGURE;
			break;
		case IDC_MAINHELP:
			DestroyWindow(stInfo.hWndAbout);
			stInfo.hWndAbout=CreateDialog(stMod.hDllInstance,MAKEINTRESOURCE(IDD_HELP),hwnd,(DLGPROC)Helpproc);
			ShowWindow(stInfo.hWndAbout,SW_SHOW);
			SetFocus(GetDlgItem(hwnd,IDC_MAINHELP));
			stInfo.AboutID = IDC_MAINHELP;
			break;
		case IDC_HISTORY:
			DestroyWindow(stInfo.hWndAbout);
			stInfo.hWndAbout=CreateDialog(stMod.hDllInstance,MAKEINTRESOURCE(IDD_HISTORY),hwnd,(DLGPROC)Historyproc);
			ShowWindow(stInfo.hWndAbout,SW_SHOW);
			SetFocus(GetDlgItem(hwnd,IDC_HISTORY));
			stInfo.AboutID = IDC_HISTORY;
			break;
		}
		break;
	case WM_INITDIALOG:
		stInfo.hWndAbout=CreateDialog(stMod.hDllInstance,MAKEINTRESOURCE(IDD_CONFIGURE),hwnd,(DLGPROC)Configproc);
		ShowWindow(stInfo.hWndAbout,SW_SHOW);
		SetFocus(GetDlgItem(hwnd,IDD_CONFIGURE));
        stInfo.AboutID = IDD_CONFIGURE;
		break;
	case WM_CLOSE:
		EndDialog(hwnd,0);
		return TRUE;
	}
	return FALSE;
}

BOOL CALLBACK Helpproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	switch(msg)
	{
	case WM_INITDIALOG:
		{
			RECT r;
			POINT stPoint;
			GetWindowRect(GetDlgItem(GetParent(hwnd),IDC_STATIC1),&r);
			stPoint.x=r.left;
			stPoint.y=r.top;
			ScreenToClient(GetParent(hwnd),&stPoint);
			SetWindowPos(hwnd,0,stPoint.x,stPoint.y,r.right-r.left,r.bottom-r.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
			SetWindowPos(GetDlgItem(hwnd,IDC_EDIT1),0,0,0,r.right-r.left,r.bottom-r.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
			if(stMod.hDllInstance != NULL)
			{
				HRSRC foundSRC= FindResource(stMod.hDllInstance,MAKEINTRESOURCE(IDR_SHORTCUT),"TEXT");
				if(foundSRC == NULL)
				{
					break;
				}

				HGLOBAL foundResource1 = LoadResource(stMod.hDllInstance,foundSRC);

				if(foundResource1 == NULL)
				{
					break;
				}

				SendDlgItemMessage(hwnd,IDC_EDIT1,WM_SETTEXT,0,(LPARAM)(char*)LockResource(foundResource1));
			}
		}
		break;
	case WM_CLOSE:
		EndDialog(hwnd,0);
		return TRUE;
	}
	return FALSE;
}

BOOL CALLBACK Historyproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	switch(msg)
	{
	case WM_INITDIALOG:
		{
			POINT stPoint;
			RECT r;
			GetWindowRect(GetDlgItem(GetParent(hwnd),IDC_STATIC1),&r);
			stPoint.x=r.left;
			stPoint.y=r.top;
			ScreenToClient(GetParent(hwnd),&stPoint);
			SetWindowPos(hwnd,0,stPoint.x,stPoint.y,r.right-r.left,r.bottom-r.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
			SetWindowPos(GetDlgItem(hwnd,IDC_EDIT1),0,0,0,r.right-r.left,r.bottom-r.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);

			HRSRC foundSRC = FindResource(stMod.hDllInstance,MAKEINTRESOURCE(IDR_HISTORY),"TEXT");
			
			if(foundSRC == NULL)
			{
				break;
			}

			HGLOBAL foundResource1 = LoadResource(stMod.hDllInstance,foundSRC);

			if(foundResource1 == NULL)
			{
				break;
			}

			SendDlgItemMessage(hwnd,IDC_EDIT1,WM_SETTEXT,0,(LPARAM)(char*)LockResource(foundResource1));
		}
		break;
	case WM_CLOSE:
		EndDialog(hwnd,0);
		return TRUE;
	}
	return FALSE;
}

BOOL CALLBACK Aboutproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	POINT stPoint;
	RECT r;
	HDC hdc;
	char *txt[]={
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		"=> This is Freeware <= ",
		" ",
		" ",
		"I sincerely thanks to",
		" ",
		"R.Venkattathal",
		" ",
		"Sivakami.R,",
		" ",
		"Ratha krishnan.K",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		"Developed By",
		" ",
		"Kannan K,",
		" ",
		"Email-Id:softkannan@gmail.com",
		" ",
		" ",
		" ",
		" ",
		">>>> Thanks to all who helped this success!!! <<<<",
		" ",
		" ",
		" ",
		"Copyright K.Kannan",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" ",
		" "//70
	};
	int totalLines = 56;
	int iIndex,dIndex;
	TEXTMETRIC txtm;
	switch(msg)
	{
	case WM_INITDIALOG:

		GetWindowRect(GetDlgItem(GetParent(hwnd),IDC_STATIC1),&r);
		stPoint.x = r.left;
		stPoint.y = r.top;
		ScreenToClient(GetParent(hwnd),&stPoint);
		SetWindowPos(hwnd,0,stPoint.x,stPoint.y,r.right-r.left,r.bottom-r.top,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
		SetWindowPos(GetDlgItem(hwnd,IDC_STATIC1),0,0,0,r.right-r.left,((r.bottom-r.top)/4)*3,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
		SetWindowPos(GetDlgItem(hwnd,IDC_STATIC2),0,0,((r.bottom-r.top)/4)*3+10,r.right-r.left,((r.bottom-r.top)/4)-10,SWP_SHOWWINDOW|SWP_NOOWNERZORDER);
		SetTimer(hwnd,ID_TIME,50,0);
		stInfo.AboutprocTimerCount = 0;
		stInfo.iTimerIncrement = 0;

		return FALSE;
	case WM_TIMER:
		if(LOWORD(wparam)==ID_TIME)
		{
			
			GetClientRect(GetDlgItem(hwnd,IDC_STATIC1),&r);
			hdc=GetWindowDC(GetDlgItem(hwnd,IDC_STATIC1));
			FillRect(hdc,&r,CreateSolidBrush(RGB(0,0,0)));
			GetTextMetrics(hdc,&txtm);
			dIndex=(r.bottom/txtm.tmHeight)+1;
			
			r.top -= stInfo.iTimerIncrement;
			r.bottom = r.top + txtm.tmHeight;
			
		
            if(r.bottom < 1)
			{
				stInfo.AboutprocTimerCount++;
				if(stInfo.AboutprocTimerCount > totalLines-dIndex)
				{
					stInfo.AboutprocTimerCount=0;
				}
				stInfo.iTimerIncrement = 0;
				GetClientRect(GetDlgItem(hwnd,IDC_STATIC1),&r);
				r.top -= stInfo.iTimerIncrement;
				r.bottom = r.top + txtm.tmHeight;
			
			}
			stInfo.iTimerIncrement++;
			
			SetTextColor(hdc,RGB(255,255,255));
			SetBkMode(hdc,TRANSPARENT);
			for(iIndex = stInfo.AboutprocTimerCount ;iIndex < (dIndex + stInfo.AboutprocTimerCount);iIndex++)
			{
				DrawText(hdc,txt[iIndex],-1,&r,DT_CENTER);
				r.top = r.bottom;
				r.bottom += txtm.tmHeight;
				//TextOut(hdc,0,0,txt[0],strlen(txt[0]));
			}
			ReleaseDC(GetDlgItem(hwnd,IDC_STATIC1),hdc);
		}
		break;
	case WM_LBUTTONUP:
		KillTimer(hwnd,ID_TIME);
		SetTimer(hwnd,ID_TIME,50,0);
		break;
	case WM_LBUTTONDOWN:
		KillTimer(hwnd,ID_TIME);
		break;
	case WM_COMMAND:
		switch(LOWORD(wparam))
		{
		case IDC_STATIC2:
			SendMessage(stMod.hMainWindow,WM_USER,0,241);
			SendMessage(stMod.hMainWindow,WM_USER,(WPARAM)"www.thex.com",241);
			ShellExecute(hwnd,"Open","iexplore.exe","www.thex.com",NULL,SW_SHOWNORMAL);
			break;
		}
		break;
	case WM_CLOSE:
		KillTimer(hwnd,ID_TIME);
		EndDialog(hwnd,0);
		return TRUE;
	}
	return FALSE;
}

LRESULT CALLBACK MainWindowproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	POINT stPoint;
	RECT r;

	switch(msg)
	{
	//initilize
	case WM_CREATE:
		DragAcceptFiles(hwnd,TRUE);
		break;
	//accept the dropted files
	case WM_DROPFILES:
		SendMessage(stMod.hMainWindow,WM_DROPFILES,wparam,lparam);
		DragFinish((HDROP)wparam);
		return 0;
	//set min of window size
	case WM_GETMINMAXINFO:
            {
                LPMINMAXINFO lpmm = (LPMINMAXINFO) lparam;
                lpmm->ptMinTrackSize.x = MIN_WINDOW_SIZEX;
                lpmm->ptMinTrackSize.y = MIN_WINDOW_SIZEY;
			}
            return 0;
	//set the window caption bar height and order
	case WM_SETTINGCHANGE:
		stInfo.CapHeight = GetSystemMetrics(SM_CYSMCAPTION)+GetSystemMetrics(SM_CYFRAME);
		stInfo.Xborder = GetSystemMetrics(SM_CXFRAME);
		stInfo.Yborder = GetSystemMetrics(SM_CYFRAME);
		break;
	//redraw the skin
	//case WM_ACTIVATE:
	//case WM_SETFOCUS:
	//case WM_KILLFOCUS:
	//case WM_ERASEBKGND:
	//case WM_NCPAINT:
	case WM_NCLBUTTONDOWN:
	if(wparam == HTCLOSE)
	{
		//DisplayInfo("Hi","Test");
		//PostQuitMessage(0);
		PostMessage(hwnd,WM_CLOSE,0,0);
		return TRUE;
	}
    break;
	case WM_UNKNOWN_MSG:
	case WM_NCACTIVATE:
	case WM_NCPAINT:
		Paint(hwnd);
		return 1;
	//process the mouse move and set the custom cursor
	case WM_MOUSEMOVE:
		SetCursor(stInfo.hCursor);
		return 0;
	//set custom cursor
	case WM_SETCURSOR:
		SetCursor(stInfo.hCursor);
		return TRUE;
	//process the window move and size
	case WM_MOVE:
	case WM_SIZE:
		if(stGr.pIVideoWindow)
		{
				GetClientRect(stInfo.hwnd,&r);
				stGr.pIVideoWindow->SetWindowPosition(r.left,r.top,r.right,r.bottom);
		}
		return 0;
	//process the left button down presses
	case WM_LBUTTONDOWN:
		//this for the window movement
		stInfo.WindowMovementflag = TRUE;
		//get the mouse position
		GetCursorPos(&stInfo.CurPos);
		//try to set the focus
		if(stGr.pIVideoWindow)
		{
			if(!stInfo.FullScreenFlag && stInfo.EnableEffect)
			{
				SetFocus(hwnd);
			}
		}
		break;
	//this one feature that intelegent control method.
	//process the right up mostly for the window movement
	case WM_LBUTTONUP:
		//check the flag
		if(stInfo.WindowMovementflag==TRUE)
		{
			stInfo.WindowMovementflag = FALSE;
			//get the current mouse pos
			GetCursorPos(&stPoint);
			//guess you draged the mouse verticaly 
			if(((stPoint.y - stInfo.CurPos.y) < 50)&&((stPoint.y - stInfo.CurPos.y) > -50))
			{
				//here we check the up side down or vice versa
				if((stPoint.x - stInfo.CurPos.x) > 50)
				{
					SendMessage(stMod.hMainWindow,WM_COMMAND,40148,0);
					if((stPoint.x - stInfo.CurPos.x) > 250)
					{
						SendMessage(stMod.hMainWindow,WM_COMMAND,40148,0);
					}

				}
				else if((stPoint.x - stInfo.CurPos.x) < -50)
				{
					SendMessage(stMod.hMainWindow,WM_COMMAND,40144,0);
					if((stPoint.x-stInfo.CurPos.x) < -250)
					{
						SendMessage(stMod.hMainWindow,WM_COMMAND,40144,0);
					}

				}
			}
			//check the horizontal movement
			if(((stPoint.x - stInfo.CurPos.x) < 50) && ((stPoint.x - stInfo.CurPos.x) > -50))
			{
				//left right or right left
				if((stPoint.y - stInfo.CurPos.y) > 50)
				{
					SendMessage(stMod.hMainWindow,WM_COMMAND,40048,0);
				}
				else if((stPoint.y - stInfo.CurPos.y) < -50)
				{
					SendMessage(stMod.hMainWindow,WM_COMMAND,40044,0);
				}
			}
			
		}
		break;
	//process mouse wheel
	case WM_MOUSEWHEEL:
		if(((short)HIWORD(wparam)) > 0)
		{
			SendMessage(stMod.hMainWindow,WM_COMMAND,40148,0);
		}
		else
		{
			SendMessage(stMod.hMainWindow,WM_COMMAND,40144,0);
		}
		break;
	//process right button press
	case WM_NCRBUTTONDOWN:
		SetCursor(stInfo.hCursor);
		GetCursorPos(&stPoint);
		TrackPopupMenu(stInfo.hmenumain,TPM_LEFTALIGN,stPoint.x,stPoint.y,0,hwnd,0);
		return TRUE;
	case WM_RBUTTONDOWN:
		SetCursor(stInfo.hCursor);
		GetCursorPos(&stPoint);
		TrackPopupMenu(stInfo.hmenumain,TPM_LEFTALIGN,stPoint.x,stPoint.y,0,hwnd,0);
		break;
	//process double click
	case WM_LBUTTONDBLCLK:
		ToggleFullScreen();
		break;
	//process middle button
	case WM_MBUTTONDOWN:
		SendMessage(stMod.hMainWindow,WM_COMMAND,40046,0);
		break;
	//process command message
	case WM_COMMAND:
		ProcessCommand(hwnd,msg,wparam,lparam);
		break;
	//process keydowns
	case WM_KEYDOWN:
		ProcessKeyDown(hwnd,msg,wparam,lparam);
		return 0;
	//process GRAPHNOTIFY comes from the filter graph
	case WM_GRAPHNOTIFY:
		if(stGr.pIEvent)
		{
			LONG evcode,eparam,eparam1;

			while((stGr.pIEvent)&&SUCCEEDED(stGr.pIEvent->GetEvent(&evcode,&eparam,&eparam1,0)))
			{
				if(stGr.pIEvent)
				{
					stGr.pIEvent->FreeEventParams(evcode,eparam,eparam1);
				}
				//media complete
				if(EC_COMPLETE==evcode)
				{
					SendMessage(stMod.hMainWindow,WM_COMMAND,40048,0);
					return 0;
				}
				
			}
		}
		return 0;
	//process the close
	case WM_CLOSE:
		DragAcceptFiles(hwnd,FALSE);
		Stop();
		DestroyWindow(hwnd);
		return 0;
	}
	return DefWindowProc(hwnd,msg,wparam,lparam);
}



//Fullscreen window proc
LRESULT CALLBACK CustomFullScreenWndproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	HRGN hrgn;
	RECT r;
	
	switch(msg)
	{
	case WM_CREATE:
		
		GetWindowRect(GetDesktopWindow(),&r);
		SetWindowPos(stInfo.hwndfull,HWND_TOPMOST,0,0,r.right,r.bottom,SWP_SHOWWINDOW);
		hrgn=CreateRectRgn(0,0,r.right,r.bottom);
		SetWindowRgn(stInfo.hwndfull,hrgn,FALSE);
		return 0;
	case WM_MOUSEMOVE:
		SetCursor(stInfo.hCursor);
		return 1;
	case WM_SETCURSOR:
		SetCursor(stInfo.hCursor);
		return TRUE;
	case WM_LBUTTONDBLCLK:
	case WM_LBUTTONUP:
	case WM_LBUTTONDOWN:
	case WM_MBUTTONDOWN:
	case WM_MBUTTONUP:
	case WM_RBUTTONUP:
	case WM_RBUTTONDBLCLK:
	case WM_RBUTTONDOWN:
	case WM_KEYDOWN:
	case WM_COMMAND:
	case WM_MOUSEWHEEL:
		MainWindowproc(stInfo.hwnd,msg,wparam,lparam);
		return 0;
	case WM_SETTINGCHANGE:
	case WM_KILLFOCUS:
		if(stInfo.FullScreenFlag)
		{
			ToggleFullScreen();
		}
		break;
	case WM_CLOSE:
		DestroyWindow(hwnd);
		return 0;
	}
	return DefWindowProc(hwnd,msg,wparam,lparam);
}


BOOL CALLBACK Propertiesproc(HWND hwnd,UINT msg,WPARAM wparam,LPARAM lparam)
{
	switch(msg)
	{
	case WM_INITDIALOG:
		{
			EnumFilters(stGr.pGraphFilter , GetDlgItem(hwnd,IDC_FILTERLIST));
		}
		break;
	case WM_COMMAND:
		{
			char szName[MAX_FILTER_NAME];

			switch(wparam)
			{
			case IDC_SHOW:
				{
					SendDlgItemMessage(hwnd,IDC_FILTERLIST,LB_GETTEXT,SendDlgItemMessage(hwnd,IDC_FILTERLIST,LB_GETCURSEL,0,0),(LPARAM)szName);
					ShowFilterPropertyPageByName(stGr.pGraphFilter,szName,hwnd);
				}
				break;
			}
		}
        break;
	case WM_CLOSE:
		EndDialog(hwnd,0);
		stInfo.ShowFilterProperty = FALSE;
		return TRUE;
	}
	return FALSE;
}

//**************************Audio Effect******************************
//
//
//
//
//Called when the audio stream open
int Audio::open(int bps,int nch,int srate)
{
	int r=0;
	r=stMod.outMod->Open(srate,nch,bps,-1,-1);
	stMod.SetInfo((srate * (bps / 8) * nch) / 1000,srate / 1000,nch,1);
	stMod.SAVSAInit(0,srate);
	stMod.VSASetInfo(nch,srate);
	
	return r;
}

//Called when file playing
int Audio::write(BYTE* samples,int numsamples,int bps,int nch,int srate)
{
	
	int t=0;//stMod.GetOutputTime();
	
	int numSample=(numsamples)/(sizeof(short int)*nch);
				
	if (stMod.dsp_isactive()&&stInfo.EnableDSPEffect)
	{
		stMod.dsp_dosamples((short int*)samples,numSample,bps,nch,srate);
	}

	stMod.SAAddPCMData((char *)samples,nch,bps,t);
	stMod.VSAAddPCMData((char *)samples,nch,bps,t);

	if(Enable)
	{
		stMod.outMod->Write((char*)samples,numsamples);
		ZeroMemory(samples,numsamples);
	}
				
	return 0; 
}
//Called when buffer was flushed
void Audio::flush()
{
	stMod.outMod->Flush(0);
}
//Called whle closing the stream
void Audio::close()
{
	stMod.outMod->Flush(0);
	stMod.outMod->Close();
}
//Destructor
Audio::Audio()
{
	Enable=0;
}




